<?php

class TaxonomyService extends FServiceBase
{
    /**
    * Lookup list service 
    * 
    * @param array $params
    *   type int|string id|alias of vocabulary
    *   root int|string id|alias of category
    *   module string module id
    *   state int state of vocabulary default Vocabulary::STATE_ACTIVE
    * @return array term recursive
    */
    public function getList($params)
    {
        $vocabulary = $this->getParam($params,'type',null);
        $term = $this->getParam($params,'root',null);
        $module = $this->getParam($params,'module',null);
        $state = $this->getParam($params,'state',Vocabulary::STATE_ACTIVE);
        
        $data = array();
        //find vocabulary
        $criteria = new CDbCriteria();
        $criteria->compare('module', $module);
        $criteria->compare('state', $state);
        if (!is_null($vocabulary))
        {
            if (is_numeric($vocabulary))
            {
                $criteria->compare('id',$vocabulary);
            }
            else
            {
                $criteria->compare('alias',$vocabulary);
            }
        }
        $model = Vocabulary::model()->find($criteria);
        if (is_object($model))
        {
            //find terms recursive
            $root = $this->findTermRoot($model->id, $term, $state);
            if (count($root))
            {
                foreach ($root as $parent)
                {
                    $data[] = $this->findTermsRecursive($parent, 0, '/', $state);
                }
            }
        }
        //return only the categories
        if (!empty($term))
        {
            $data = $this->findSubTermsRecursive($data, $term);
        }
        return $this->result->processed('data', $data);
    }
    
    protected function findTermRoot($vocId, $id = null, $state = Term::STATE_ACTIVE)
    {
        $criteria = new CDbCriteria();
        $criteria->compare('v_id', $vocId);
        $criteria->compare('state', $state);
        if (!empty($id)) {
            if (is_string($id))
                $criteria->addCondition('alias = :id');
            if (is_numeric($id))
                $criteria->addCondition('id = :id');
            $criteria->params[':id'] = $id;
        }
        else
            $criteria->addCondition('id NOT IN (SELECT term_id FROM '.SITE_TABLE_PREFIX.'taxonomy_term_hierarchy)');
        $criteria->order = 'ordering';
        return Term::model()->findAll($criteria);
    }
    
    /**
    * find terms recursive
    * 
    * @param Term $parent
    */
    protected function findTermsRecursive($parent, $level=0, $path='/', $state = Term::STATE_ACTIVE)
    {
        $data = $parent->attributes;
        $data['level'] = $level++;
        $vob = Vocabulary::model()->findByPk($parent->v_id);
        if (is_object($vob))
        {
            $propertyClassName = $vob->propertyClassName;
            if (!empty($propertyClassName))
            {
                $model = new $propertyClassName;
                $property = $model->findByAttributes(array('term_id'=>$parent->id, 'status' => $state));
                if (is_object($property))
                {
                    $properties = $property->attributes;
                    unset($properties['id'], $properties['status'], $properties['creation_datetime'],
                        $properties['last_update'], $properties['created_by'], $properties['updated_by'], $properties['term_id']);
                    $data['properties']=$properties;
                }
            }
        }
        
        $children = $parent->children(array('order'=>'ordering','condition'=>'children.state=:state','params'=>array(':state'=>$state)));
        if (is_array($children) && count($children))
        {
            $data['children'] = array();
            foreach ($children as $term)
            {
                 $data['children'][] = $this->findTermsRecursive($term, $level, '/', $state);
            }
        }
        return $data;
    }
    
    protected function findSubTermsRecursive($items, $term)
    {
        if (count($items))
        {
            foreach ($items as $item)
            {
                if (is_numeric($term))
                {
                    if ($item['id'] == $term)
                    {
                        return $item;
                    }
                }
                else
                {
                    if ($item['alias'] == $term)
                    {
                        return $item;
                    }
                }
                if (isset($item['children']) && count($item['children']))
                {
                    return $this->findSubTermsRecursive($item['children'], $term);
                }
            }
        }
        return false;
    }
}